
namespace ShoppingCart.DataAccess
{
	using System;
    using System.Data;
    using Microsoft.Practices.EnterpriseLibrary.Data;
	using ShoppingCart.Business.Entity;
    using ShoppingCart.Business.Entity.Collections;

	/// <summary>
	/// Represents the DataAccess of ProductoDepartamentoData.
	/// </summary>
	public class ProductoDepartamentoData : Singleton<ProductoDepartamentoData>
	{
		#region Attributes

		private readonly Database BaseDatos = DatabaseFactory.CreateDatabase();

		#endregion

		#region Methods


		/// <summary>
		/// Selects all records from the ProductoDepartamento table by a foreign key.
		/// </summary>
		public PrecioStock Obtener(int idProducto, int idDepartamento)
		{
			var productoDepartamento = default(PrecioStock);
			var comando = BaseDatos.GetStoredProcCommand("SelectProductoDepartamento");

			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);
			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, idDepartamento);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    productoDepartamento = new PrecioStock
                    {
                        Producto = ProductoData.Instancia.Obtener(idProducto),
                        Departamento = DepartamentoData.Instancia.Obtener(idDepartamento),
                        Stock = lector.GetInt32(lector.GetOrdinal("Stock")),
                        Precio = lector.GetDecimal(lector.GetOrdinal("Precio")),
                        Estado = lector.GetBoolean(lector.GetOrdinal("Estado"))
                    };
				}
			}
			comando.Dispose();
			return productoDepartamento;
		}

		/// <summary>
		/// Saves a record to the ProductoDepartamento table.
		/// </summary>
		public int Agregar(PrecioStock precioStock)
		{
			var comando = BaseDatos.GetStoredProcCommand("InsertProductoDepartamento");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, precioStock.Producto.IdProducto);
			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, precioStock.Departamento.IdDepartamento);
			BaseDatos.AddInParameter(comando, "Stock", DbType.Int32, precioStock.Stock);
			BaseDatos.AddInParameter(comando, "Precio", DbType.Currency, precioStock.Precio);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Boolean, precioStock.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Agregar ProductoDepartamento.");

			comando.Dispose();
			return 1;
		}

        public int Agregar(PrecioStockCollection coleccion)
        {
            using (var connection = BaseDatos.CreateConnection())
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    try
                    {
                        var comando = BaseDatos.GetStoredProcCommand("InsertProductoDepartamento");
                        BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32);
                        BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32);
                        BaseDatos.AddInParameter(comando, "Stock", DbType.Int32);
                        BaseDatos.AddInParameter(comando, "Precio", DbType.Currency);
                        BaseDatos.AddInParameter(comando, "Estado", DbType.Boolean);

                        foreach (var precioStock in coleccion)
                        {
                            BaseDatos.SetParameterValue(comando, "IdProducto", precioStock.Producto.IdProducto);
                            BaseDatos.SetParameterValue(comando, "IdDepartamento", precioStock.Departamento.IdDepartamento);
                            BaseDatos.SetParameterValue(comando, "Stock", precioStock.Stock);
                            BaseDatos.SetParameterValue(comando, "Precio", precioStock.Precio);
                            BaseDatos.SetParameterValue(comando, "Estado", precioStock.Estado);

                            var resultado = BaseDatos.ExecuteNonQuery(comando, transaction);
                            if (resultado == 0) throw new Exception("Error al Agregar ProductoDepartamento.");
                        }

                        transaction.Commit();
                        comando.Dispose();
                        return 1;
                    }
                    catch (Exception)
                    {
                        transaction.Rollback();
                        throw;
                    }
                }
            }
        }

	    /// <summary>
		/// Updates a record in the ProductoDepartamento table.
		/// </summary>
		public bool Modificar(PrecioStock productoDepartamento)
		{
			var comando = BaseDatos.GetStoredProcCommand("UpdateProductoDepartamento");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, productoDepartamento.Producto.IdProducto);
			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, productoDepartamento.Departamento.IdDepartamento);
			BaseDatos.AddInParameter(comando, "Stock", DbType.Int32, productoDepartamento.Stock);
			BaseDatos.AddInParameter(comando, "Precio", DbType.Currency, productoDepartamento.Precio);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Boolean, productoDepartamento.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Modificar ProductoDepartamento.");

			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the ProductoDepartamento table by its primary key.
		/// </summary>
		public bool Eliminar(int idProducto, int idDepartamento)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteProductoDepartamento");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);
			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, idDepartamento);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar ProductoDepartamento.");
			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the ProductoDepartamento table by a foreign key.
		/// </summary>
		public void EliminarPorIdDepartamento(int idDepartamento)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteProductoDepartamentoByIdDepartamento");
			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, idDepartamento);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar ProductoDepartamento.");
			comando.Dispose();
		}

		/// <summary>
		/// Deletes a record from the ProductoDepartamento table by a foreign key.
		/// </summary>
		public void EliminarPorIdProducto(int idProducto)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteProductoDepartamentoByIdProducto");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar ProductoDepartamento.");
			comando.Dispose();
		}

		/// <summary>
		/// Selects all records from the ProductoDepartamento table by a foreign key.
		/// </summary>
		public ProductoCollection ListarPorIdDepartamento(int idDepartamento)
		{
            var entidades = new ProductoCollection();
			var comando = BaseDatos.GetStoredProcCommand("SelectProductoDepartamentoByIdDepartamento");

			BaseDatos.AddInParameter(comando, "IdDepartamento", DbType.Int32, idDepartamento);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
					entidades.Add(new Producto
					{
						IdProducto = lector.GetInt32(lector.GetOrdinal("IdProducto")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
						Descripcion = lector.IsDBNull(lector.GetOrdinal("Descripcion"))? default(string) : lector.GetString(lector.GetOrdinal("Descripcion")),
						Icono = lector.IsDBNull(lector.GetOrdinal("Icono"))? default(string) : lector.GetString(lector.GetOrdinal("Icono")),
						Imagen = lector.IsDBNull(lector.GetOrdinal("Imagen"))? default(string) : lector.GetString(lector.GetOrdinal("Imagen")),
						Stock = lector.GetInt32(lector.GetOrdinal("Stock")),
						Precio = lector.GetDecimal(lector.GetOrdinal("Precio")),
						Estado = lector.GetBoolean(lector.GetOrdinal("Estado")),
                        Linea = LineaData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdLinea")))
					});
				}
			}
			comando.Dispose();
			return entidades;
		}

		/// <summary>
		/// Selects all records from the ProductoDepartamento table by a foreign key.
		/// </summary>
		public PrecioStockCollection ListarPorIdProducto(int idProducto)
		{
			var entidades = new PrecioStockCollection();
			var comando = BaseDatos.GetStoredProcCommand("SelectProductoDepartamentoByIdProducto");

			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    entidades.Add(new PrecioStock
                    {
                        Producto = ProductoData.Instancia.Obtener(idProducto),
                        Departamento = DepartamentoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDepartamento"))),
                        Stock = lector.GetInt32(lector.GetOrdinal("Stock")),
                        Precio = lector.GetDecimal(lector.GetOrdinal("Precio")),
                        Estado = lector.GetBoolean(lector.GetOrdinal("Estado"))
                    });
				}
			}
			comando.Dispose();
			return entidades;
		}

		#endregion
	}
}
